home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-08-16 | 33.3 KB | 1,154 lines |
-
-
-
- USING GUILE IN YOUR PROGRAMS
- and
- WRITING NEW BUILT-IN PROCEDURES AND TYPES
-
-
-
- INTRODUCTION
- ============
-
- This file will teach you how to make Guile the extension
- language in your program. It will show you:
-
- - How to initialize the interpreter.
-
- - Ways to call the interpreter to run extension programs or
- evaluate the code in C strings.
-
- - Ways to define new functions in C that are callable by Guile
- programs.
-
- - Ways to define new data types in C that can be manipulated by
- Guile programs.
-
-
- To bring this documentation to life, a more or less complete example
- of using Guile is needed. None is ready for this first release of
- Guile, but one will be ready soon -- stay tuned for a version of Oleo
- that is extensible using Guile.
-
-
-
-
- INVOKING GUILE FROM YOUR PROGRAM
- ================================
-
- * Compiling
-
- If you use the functions and types described in this file, your
- source files should include:
-
- #include "guile.h"
-
- When you compile, you should link against the file `libguile.a'
- which is built and installed by this distribution.
-
-
-
-
- * Errors
-
- Several functions return a value of type GSCM_status. This type
- represents an error code.
-
- The macro GSCM_OK is a value of type GSCM_status that is used
- to indicate success. It is the normal return value of these
- functions. Any other value indicates an error.
-
- An error message can be generated from a GSCM_status value
- using the function gscm_error_msg. Here is an example:
-
- GSCM_status status;
-
- status = initialize_gscm (0, argc, argv)
- if (status != GSCM_OK)
- {
- fputs (gscm_error_msg (status), stderr);
- fputc ('\n', stderr);
- exit (1);
- }
-
- There is a specification that says all error messages must be an
- integral number of complete, punctuated, sentences. If the message is
- more than one line, the first line will be a summary of the message.
- The message is not terminated by a newline.
-
-
-
- * Initializing The Interpreter
-
- Before calling any other Guile functions, you must initialize the
- state of the interpreter using this function:
-
-
- GSCM_status
- initialize_gscm (initfile, argc, argv)
- char *initfile;
- int argc;
- char **argv;
-
- Initialize the internal state of the interpreter.
-
- This copies the arguments to be the return value of the Scheme
- procedure `(program-arguments)'.
-
- This loads the Scheme code found at INITPATH. If INITPATH is
- NULL, the environment variable GUILE_INIT_FILE is checked. If
- that is empty, a built-in file name is used. To prevent any
- file from being evaluated, pass the value of the macro
- GUILE_NO_INIT_FILE. (In normal circumstances, you should pass
- NULL and accept the user's or the library's default.)
-
- Normally this function returns GSCM_OK. If the return value
- is anything else, an error has occured. (See the general
- comments on errors, above). If an error occurs, the interpreter
- has not been initialized and may not be used.
-
- Normally, you should only need to call this function once per
- invocation of your program.
-
- There are exceptions to the rule that initialize_gscm must be called
- before any other gscm functions. These exceptions are functions that
- supply extra parameters to the initialization process -- parameters for
- which the default should normally be reasonable. These are:
-
- void gscm_verbosity (int n)
- Set the level of verbosity. See scm.texi about `(verbose n)'.
-
- void gscm_take_stdin ()
- If this is called, then the interpreter will create a port
- called "*stdin*" that refers the stdio file FILE*, stdin.
- On systems that permit it, buffering will be turned off for
- that stream.
-
- The function initialize_gscm in turn calls the initialization function
- for all parts of libguile -- even those which may be considered
- optional. If you want an interpreter with only a subset of the usual
- functionality (perhaps to save on text size) you can use an alternative
- function to initialize gscm, gscm_init_from_fn:
-
- GSCM_status
- gscm_init_from_fn (initfile, argc, argv, init_fn)
- char *initfile;
- int argc;
- char **argv;
- void (*init_fn) ();
-
-
- Like initialize_gscm, but calls `init_fn' instead of
- directly calling initialization routines for optional
- parts of libguile.
-
- init_fn may be a function you write, or one of the library
- functions `guile_ks' or `guile_mini'. `guile_ks' creates
- a kitchen-sink interpreter, with all options turned on.
- `guile_mini' creates a minimal interpreter.
-
- The currently available init functions (those called from
- guile_ks) are:
-
- scm_init_ioext();
- scm_init_posix();
- scm_init_socket();
- scm_init_unix();
- scm_init_ioext();
- scm_init_rgx();
- scm_init_guile();
- scm_init_ctax();
- scm_init_tcl();
- scm_init_tk();
-
-
- * Creating Top Levels
-
- In order to evaluate expressions, you must provide a top level
- environment (aka global name-space) in which to evaluate the code.
- More than one top level environment may exist at a time.
-
- There are two functions that relate to creating and releasing
- top levels:
-
-
-
- GSCM_status
- gscm_create_top_level (GSCM_top_level * answer)
-
- Return a new top level environment.
-
-
-
- void
- gscm_destroy_top_level (GSCM_top_level)
-
- Release all resources associated with a top level environment.
-
-
- When you release a top level environment using gscm_destroy_top_level,
- the data from the top level is not immediately freed. Instead, all
- pointers to the information held on behalf of your application will be
- dropped, clearing the way for the top level to be garbage collected.
-
-
- * Invoking the Interpreter
-
- There are two basic ways to invoke the interpreter: so that it
- reads commands from a string, and so that it reads commands
- from a file.
-
- GSCM_status
- gscm_eval_str (answer, toplvl, str)
- char ** answer;
- GSCM_top_level toplvl;
- char * str;
-
- GSCM_status
- gscm_eval_file (answer, toplvl, file_name)
- char ** answer;
- GSCM_top_level toplvl;
- char * file_name;
-
- These forms return a newly allocated string in *answer.
- The caller is responsible for freeing the string using `free'.
-
-
- EXTENDING GUILE WITH NEW FUNCTIONS
- ==================================
-
- * Defining New Modules in C
-
- As you add Guile to your programs, you will almost certainly want to
- define new procedures which can be called by extension programs. This
- section will show you how.
-
- Before introducing the functions, it is important to explain how
- Scheme objects are represented and how your code can manipulate the
- objects correctly.
-
-
-
- * The Type `SCM'
-
- Scheme data types are objects like pairs and closures which have
- special meaning to the interpreter. To a C program, all such objects
- are of type SCM.
-
- Two functions that return type SCM have already been described:
- gscm_seval_file and gscm_seval_str. In the sections that follow,
- SCM values are used throughout.
-
- There are some important conventions for manipulating SCM values.
- They are the subject of this section.
-
- The type SCM is opaque to C programs. It is not a structure, union,
- or pointer type (in fact, SCM is normally defined as a typedef for
- long integers, though you should not in any way rely on this fact in
- your code). Values of type SCM are manipulated entirely by functions
- such as those documented in this file.
-
- SCM objects are garbage collected. That means that when the
- interpreter determines that the object is no longer needed, it is
- automaticly freed. Very little explicit action is required from
- programmers to accomplish this. You can be sure that GC will work
- correctly if you follow a few simple conventions.
-
- ****************************************
- * *
- * IMPORTANT PROGRAMMING CONVENTIONS!!! *
- * *
- ****************************************
-
- There are only three places where it is safe to store an SCM value.
-
- - in function arguments and local variables,
-
- - in an array allocated by gscm_mkarray,
-
- - in the fields of a Scheme object of a type
- you are defining.
-
- These are the only places properly searched by the garbage collector
- when deciding which Scheme objects may be discarded and which must
- live.
-
- These rules imply that you can not store a Scheme value in a global
- variable or directly in malloced memory that is not part of a Scheme
- object. Instead, you must store a pointer to an array allocated
- by gscm_mkarray, and store the SCM objects in that array.
-
-
-
- HEAP STORAGE FOR SCM VALUES: gscm_mkarray, gscm_free
-
- It is generally not safe to store SCM values in malloced memory.
- (An exception to this is when the memory belongs to some Scheme
- object). It is never safe to store SCM values in global C variables.
-
- Instead, you can allocate storage for SCM values with this function:
-
- SCM *
- gscm_mkarray (int num_elts);
-
- Return storage for NUM_ELTS of SCM values, all elements
- initialized to GSCM_FALSE.
-
-
- To free memory allocated by gscm_mkarray, use
-
-
- SCM
- gscm_free (SCM *);
-
-
- So, for example, the following global declaration is wrong, because
- global storage is not one of the three places it is safe to store
- SCM values:
-
- SCM interesting_object_cache[10]; /* bogus */
-
- but this code is correct, because storage allocated by gscm_mkarray
- is one of the three places it is safe to store SCM values.
-
- SCM *interesting_object_cache;
-
- init_module ()
- {
- interesting_object_cache = gscm_mkarray (10);
- ...
- }
-
-
- [In the future, support may be added for Scheme values which are represented
- by normal C global variables -- thus creating a fourth safe place to store
- SCM value.]
-
- Function arguments, local variables, and the fields of
- application-defined Scheme objects (but *not* arrays returned by
- gscm_mkarray) are ``conservatively collected''. That means that the
- garbage collector searches those areas for anything that looks like an
- SCM value, even if in fact it is not a value your program depends on
- any longer.
-
- For that reason, it is a good idea to assign GSCM_FALSE (or some other
- neutral value) to SCM variables and structure fields which you are no
- longer using.
-
-
-
-
- * Defining new built-in procedures
-
- The following procedure is used to define new built-in functions in
- Guile. It should be used only after initialize_gscm has been called.
-
-
- void
- guile_define_procedure (name, fn, req, opt, varp, doc)
- char * name;
- SCM val;
- SCM (*fn)();
- int req;
- int opt;
- int varp;
- char * doc;
-
- This is the function used to turn a C function into a Scheme
- procedure with a top level binding.
-
- NAME is the name the function will initially be given as a top level
- binding.
-
- guile_define_procedure creates a procedure object that, when
- invoked, results in a call to FN. REQ and OPT specify the number of
- required and optional parameters. If VARP is true, the function
- takes in addition a final argument -- a list of `rest' parameters.
-
- scm_obj = FN (req1, req2, ..., opt1, opt2, ..., rest_args)
-
- Note that parameters may be omitted. For example, if OPT and VARP
- are both 0, the function will simply be called:
-
- scm_obj = FN (req1, req2, ...reqn)
-
- passing only as many arguments as specified by the REQ parameter.
-
- Optional parameters that are not supplied by the caller are passed
- the value GSCM_UNDEFINED. If rest-arguments are requested, they are
- passed as a scheme list.
-
- The total number of argument to the C function FN must not be
- greater than 10. If you need more arguments than that, write
- a function that takes a variable number of argument (VARP == 1)
- and explicitly check that the right number was passed by checking
- the length of the list of rest arguments (use gscm_length).
-
- Tips for writing documentation are appended to this file. The
- documentation system has not been implemented yet, so nothing uses
- these strings at present. In addition to following the tips, a line
- should be prepended to the doc-string that illustrates how the function
- is called (see the example which follows).
-
- By convention, the string literal of a doc string should always be
- enclosed in the macro GUILE_DOC. This allows us, at a later time,
- to find all of these strings automaticly.
-
- Here is a trivial example:
-
-
- static char elisp_car_doc[] =
- GUILE_DOC(
- "(elisp-cdr list)
- Return the cdr of CONSCELL. If arg is nil, return nil.
-
- This function differs from Scheme CDR in it's treatment of the
- empty list.
- ");
-
- extern SCM e_cdr();
-
- void
- elisp_initializer ()
- {
- gscm_define_procedure ("elisp-cdr", e_car, 1, 0, 0, elisp_car_doc);
- ...
- }
-
-
-
- * Flow of Control in Built-in Functions
-
- Calls to built-in Scheme functions have two properties that are unusual
- for C programs. Programmer's must be aware of these when writing built-in
- functions:
-
- ******************************************
- * *
- * IMPORTANT PROGRAMMING CONSIDERATION!!! *
- * *
- ******************************************
-
-
- 1. A built-in function may be aborted at almost any point
- in its execution.
-
- 2. A built-in function may be restarted any number of times
- at almost any point in its execution.
-
-
- Here is why:
-
- A built-in can be aborted at any time if:
-
- - it calls some other procedure that causes an error
-
- - an asynchronous interrupt causes an error
-
- - an interrupt or procedure call executes THROW to an
- enclosing call to CATCH
-
- - a continuation which does not include the call to the built-in
- can be invoked without first capturing the call to the built-in.
-
-
- A built-in can be restarted multiple times if a continuation is
- captured that includes the call to the built-in. Such a continuation
- might be captured either asynchronously in an interrupt handler, or
- synchronously in a procedure call. (Being captured asynchronously and
- restarted multiple times is highly unlikely -- if it happens, there is
- probably a bug in a user provided signal handler. But consideration
- of the the possibility illustrates the kind of care that is necessary
- when writing new Scheme procedures in C.)
-
- Here is an example of how you must plan for these possibilities:
-
- Suppose you wanted to write a built-in procedure reads a block of data
- from a file, computes a checksum, and returns that checksum. Before
- returning, it applies a hook procedure to the answer. You might
- naively write this code:
-
-
- /* Buggy code for a built-in function: */
-
- SCM
- compute_checksum ()
- {
- char * data;
- unsigned long sum
-
- /* Get a buffer filled with data: */
- data = malloc (100);
- read_data (data);
-
- /* Compute the checksum */
- sum = compute_checksum (data);
-
- /* Call the hook function */
- gscm_apply (checksum_hook,
- gscm_list (gscm_ulong (sum), GSCM_EOL_MARKER));
-
- free (data);
-
- return gscm_ulong (sum);
- }
-
- That function has several problems. First, consider the call to gscm_apply.
- It is quite imaginable that the procedure bound to `checksum_hook' will
- capture its continuation, perhaps returning to that continuation more than
- once. That means that `gscm_apply' may return more than once.
-
- Suppose that it does. Upon the first return, `data' is freed. Upon
- the second return, the same `data' is freed a second time -- a
- catastrophic error.
-
- On the other hand, gscm_apply might cause an error or find some other
- reason to never return. In that case, `free' will never be called,
- and there is a core leak.
-
- As a general rule, a built-in procedure can not be written to allocate
- and free resources in a linear fashion because the flow of control
- rules of Scheme make it difficult to ensure that the code will be
- executed just once, straight through.
-
- As a first fix, you might try simply doing away with the hook function,
- since that is the mostly likely source of problems:
-
- /* Still buggy code for a built-in function: */
-
- SCM
- compute_checksum ()
- {
- char * data;
- unsigned long sum
-
- /* Get a buffer filled with data: */
- data = malloc (100);
- read_data (data);
-
- /* Compute the checksum */
- sum = compute_checksum (data);
-
- free (data);
-
- return gscm_ulong (sum);
- }
-
- If that version worked, then you could call the built-in version
- %%compute-checksum and in your applications init file define:
-
- (define (compute-checksum)
- (let ((answer (%%compute-checksum)))
- (checksum-hook-fn answer)
- answer))
-
- This attempt would be the right idea: it is generally easier to code
- the problematic parts in Scheme, and to keep the C built-ins very simple.
- But alas, there is still a problem.
-
- An asynchronous signal might come along during a call to
- compute_checksum. In response, an arbitrary Scheme signal handler may
- be invoked. When signal handlers are invoked, their continuation
- resumes execution of the interrupted function. So, if the handler
- captures its continuation, parts of compute_checksum may be executed
- multiple times. For example, an interrupt during the assignment to
- `sum' might once again lead to `free' being executed multiple times
- (or not be executed at all).
-
- The problem of asynchronous interrupts can be quite serious. For
- example, an interrupt during the call to `malloc' or `free' might
- leave the heap in an inconsistent state.
-
- Here is yet a third version of `compute_checksum'. This one works:
-
-
-
- /* Ahh...sweet mystery of liveness at last i've found you:
- * (a version that works)
- */
- SCM
- compute_checksum ()
- {
- char * data;
- unsigned long sum
-
- GSCM_DEFER_INTS;
-
- /* Get a buffer filled with data: */
- data = malloc (100);
- read_data (data);
- /* Compute the checksum */
- sum = compute_checksum (data);
- free (data);
-
- GSCM_ALLOW_INTS;
-
- return gscm_ulong (sum);
- }
-
- Two macros are used: GSCM_DEFER_INTS and GSCM_ALLOW_INTS. These
- prevent asynchronous interruption. Between calls to these macros,
- nothing surprising will happen with the flow of control.
-
- There is an important restriction on the use of GSCM_DEFER_INTS
- and GSCM_ALLOW_INTS: you may not call any gscm functions between them
- For example, the first buggy example could not have been fixed by writing:
-
- /* Illegal because gscm_apply is called between GSCM_DEFER_INTS
- * and GSCM_ALLOW_INTS:
- */
- GSCM_DEFER_INTS;
- gscm_apply (checksum_hook, ...);
- GSCM_ALLOW_INTS;
-
-
- In some circumstances, a more general sort of protection is called for
- than just GSCM_DEFER_INTS and GSCM_ALLOW_INTS. Two functions defined
- below, gscm_catch and gscm_dynamic_wind provide to C programs the
- behavior of the Guile Scheme forms CATCH and DYNAMIC-WIND.
-
-
- [The documentation for this section makes it sound much more difficult
- than it really is, which is a bug since some people will be turned off
- just by the apparent complexity. Also, call-with-dynamic-root allows
- people to write call-outs that don't have these surprises -- it needs
- to be documented as well.]
-
-
-
-
- SCHEME PROCEDURES
- =================
-
- The next several sections describe functions that correspond to SCM
- procedures. They are useful when writing new built-in functions.
-
- The functions in this section should only be used from inside a
- built-in function. In particular, they should not be used except
- while the interpreter is active.
-
-
- * gscm_cons, gscm_list
-
- These functions are for manipulating lists.
-
- SCM
- gscm_cons (SCM a, SCM b)
-
- Allocate a new pair with A in the car and B in the cdr.
-
-
-
- SCM
- gscm_list (SCM elt, ...)
-
- Allocate a new list containing the ELT arguments.
-
- The value GSCM_EOL_MARKER must be passed as the last argument to
- gscm_list. It is not included in the output list.
-
-
- SCM gscm_set_car (SCM pair, SCM val)
- SCM gscm_set_cdr (SCM pair, SCM val)
- SCM gscm_car (SCM pair)
- SCM gscm_cdr (SCM pair)
-
- Just what you would expect. Also defined are gscm_caar, gscm_cadr
- and so on for all `cxr' functions up to four elements long (e.e. cddddr).
-
-
- int gscm_ilength (SCM obj)
-
- If OBJ is a proper list, return it's length. Otherwise return -1.
-
-
-
-
- * gscm_ulong, gscm_long, gscm_double.
-
- These functions convert some C number types to Scheme number types.
- C integers are converted to exact values. C floating point numbers
- are converted to inexact types.
-
- SCM
- gscm_ulong (i)
- unsigned long i;
- SCM
- gscm_long (i)
- long i;
- SCM
- gscm_double (d)
- double d;
-
- Convert a number to a Scheme object.
-
-
-
-
-
- * gscm_2_long, gscm_2_ulong, gscm_2_double
-
- These functions convert some Scheme number types into C number types.
-
- double
- gscm_2_double (obj)
- SCM obj;
-
- unsigned long
- gscm_2_ulong (out, obj)
- SCM obj;
-
- long
- gscm_2_long (obj)
- SCM obj;
-
- Convert Scheme objects to numbers.
-
-
-
- * gscm_str, gscm_str0
-
- SCM
- gscm_str (str, len)
- char * str;
- int len;
-
- Copy a string into a new Scheme object.
-
-
- SCM
- gscm_str0 (str)
-
- Copy a 0-terminated string into a new Scheme object.
-
-
-
- * gscm_2_str
-
- void
- gscm_2_str (chars, len, obj)
- char ** chars;
- int * len;
- SCM * obj;
-
- Return data from a Scheme string.
-
- *******************************************
- * NOTE!!! The obj parameter is passed by *
- * _address_, not by value. *
- *******************************************
-
- The data returned still `belongs' to the Scheme object.
- When the scope of the variable who's address is passed as OBJ
- is left, the string data becomes invalid (it may be garbage
- collected at any time). If you need the data to persist longer
- than that, you must make a private copy.
-
- The data returned also becomes invalid if you assign a new
- value to the SCM variable whose address was passed.
- For example, this code is buggy:
-
- {
- char * str;
- int len;
-
- gscm_2_str (&str, &len, scmobj);
-
- str[0] = 'a'; /* this is fine. */
-
- scmobj = some_other_obj; /* assigning to scmobj invalidates STR */
-
- str[0] = 'b'; /* this is a bug! str is no longer valid. */
- }
-
-
-
- * gscm_is_eq, gscm_is_eqv gscm_is_equal
-
- int gscm_is_eq (SCM a, SCM b)
- int gscm_is_eqv (SCM a, SCM b)
- int gscm_is_equal (SCM a, SCM b)
-
- Return 0 or 1 according to whether A and B satisfy the
- indicated equivalance.
-
-
-
- * gscm_bool, gscm_2_bool
-
- SCM gscm_bool (int cbool);
-
- Return #t or #f according to CBOOL: 0 for #f, #t otherwise.
-
-
- int gscm_2_bool (SCM bool);
-
- Return 0 if BOOL is #f, otherwise, return 1.
-
-
-
-
- * gscm_symbol, gscm_tmp_symbol
-
- SCM gscm_symbol (char * name, int len);
-
- Return a normal symbol. The second form is for 0-terminated names.
-
-
- SCM gscm_tmp_symbol (char * name, int len)
-
- Return a new symbol that is not interned in any obarray.
-
-
-
-
- * gscm_vector, gscm_vref, gscm_vset
-
- SCM gscm_vector (int size, SCM init)
-
- Create a new vector object, filled with INIT.
-
- SCM gscm_vref (SCM vector, int index)
- void gscm_vset (SCM vector, int index, SCM value)
-
- Accessor and modifier for vectors.
-
-
- * gscm_obj_length
-
- int gscm_obj_length (SCM obj)
-
- Return the length of an object or -1.
-
- Length is defined for lists, strings, symbols (treated as strings),
- and vectors. For any type for which length is not defined, -1
- is returned.
-
-
-
- * gscm_make_subr, gscm_curry
-
- It has already been shown how to define new built-ins as part of the
- initializing the interpreter. It is possible, in addition, to create
- new anonymous functions on-the-fly during the execution of built-in
- functions:
-
- SCM gscm_make_subr (int req, int opt, int varp, SCM (*fn)())
-
- Return an anonymous procedure object for the C function FN.
- The REQ, OPT, and VARP parameters are documented under
- the function gscm_define_procedure (see above).
-
-
- gscm_make_subr creates a new anonymous procedure that, when invoked,
- calls a C function. Sometimes it is useful (for example, when
- creating ``call-backs'') to specify values that will be passed for some
- of the parameters to that function. That can be done with this function:
-
-
- SCM gscm_curry (SCM procedure, SCM first_arg)
-
- Return a new procedure that is the curry of PROCEDURE with FIRST_ARG.
-
- When the new procedure is invoked, it calls the original
- procedure, supplying FIRST_ARG as the first argument. If the
- new procedure is passed additional arguments, they are
- forwarded to the original procedure as the second and
- subsequent argument.
-
-
- * gscm_catch, gscm_throw, gscm_dynamic_wind
-
- SCM gscm_catch (SCM tag, SCM thunk, SCM handler)
-
- Equivalent to the Scheme code:
-
- (catch-wind tag thunk handler)
-
-
-
-
-
- SCM gscm_throw (SCM tag, SCM value)
-
- Equivalent to the Scheme code:
-
- (throw tag value)
-
- Like the Scheme function, this C function never returns.
-
-
-
- SCM gscm_dynamic_wind (SCM entering, SCM thunk, SCM leaving)
-
- Equivalent to the Scheme code:
-
- (dynamic-wind entering thunk leaving)
-
- Like the Scheme function, this C function never returns.
-
-
- [[[Some sample code is needed that illustrates using catch/throw, d-w,
- wrap, and curry.]]]
-
-
-
- * gscm_apply
-
- SCM gscm_apply (SCM procedure, SCM list_of_args)
-
- Apply PROCEDURE to the elements of LIST_OF_ARGS, returning the result.
-
-
-
- * gscm_error
-
- All of the functions above have the property that if they are passed a
- Scheme object of incorrect type, they signal an error and do not
- return (they long jump to the root of Scheme evaluation where the
- error handler decides what to do next).
-
- Built-in functions can themselves signal errors using this function:
-
-
- SCM gscm_error (char * message, SCM args)
-
- The same as `(apply error (cons message args))'
-
- Perform an immediate, non-local exit from the calling procedure,
- signaling an error.
-
- The arguments are an error message and an arbitrary collection
- of Scheme objects.
-
-
-
-
- ADDING NEW TYPES TO GUILE
- =========================
-
- * gscm_alloc_obj, gscm_unwrap_obj
-
- These functions are used to define new types of Scheme objects, to
- instantiate them, and to access their data.
-
- The header file "guile.h" includes this definition:
-
- struct gscm_type
- {
- char * name;
- int equal_proc (SCM a, SCM b);
- int print_proc (SCM obj, SCM port, int writingp);
- void die_fn (SCM obj);
- };
-
-
- To define a new type of Scheme object, you must create one permanent
- instance of this structure type, and fill it in with data and functions
- that describe your new type.
-
- The TYPE_NAME is a 0 terminated string used only for debugging and
- when using the default printed representation of objects
- (e.g. `#<type-name 0x1000298>').
-
- You may provide EQUAL_PROC, which implements equal? for two objects of
- this type. If set to 0, then equal? for this type is no different
- than eq?.
-
- You may provide PRINT_PROC. This function is called to WRITE objects
- of this type and to DISPLAY them (WRITE and DISPLAY are two standard
- Scheme procedures for externalizing object). The parameter WRITINGP
- indicates which kind of call is being made (0 for DISPLAY, otherwise,
- WRITE). The PORT parameter is a Scheme port on which to print the
- object. SCM's port i/o functions for writing to ports are described
- later in this document. The parameter OBJ is the value to print.
- PORT should return 0 only if it has not printed the object, 1
- otherwise. If 0 is returned, or if NULL is specified as the
- PRINT_PROC, a default print routine is used.
-
- The DIE_FN is called when an instance of one of these objects has been
- garbage collected. It is passed a reference to the dying object.
- During the execution of the DIE_FN, it is important to not save any
- references to the dying object. Only resource de-allocation is
- permitted from inside a DIE_FN. DIE_FN's are never asynchronously
- interrupted, and they may not use GSCM_DEFER_INTS / GSCM_ALLOW_INTS.
- DIE_FN's may not call any gscm function other than `gscm_unwrap' (see
- below).
-
-
- SCM gscm_alloc_obj (struct gscm_type * type, int size);
-
- Allocate storage for a new Scheme object of a type you define.
- The object is allocated SIZE bytes of storage, initialized
- to all 0's. The encapsulation of the object as an SCM value
- is returned.
-
- Object's are currently restricted to be fewer than 2^15 bytes
- in size. If you need a larger object, allocate it using
- malloc and store a pointer to that object in your scheme
- object. See the notes above concerning GSCM_DEFER_INTS
- and GSCM_ALLOW_INTS before using malloc in this way.
-
-
- char * gscm_unwrap_obj (struct gscm_type * type, SCM * obj)
-
- *******************************************
- * NOTE!!! The obj parameter is passed by *
- * _address_, not by value. *
- *******************************************
-
- (See the documentation of gscm_2_str for an explanation
- of this warning).
-
- Retrieve the data Encapsulated in a Scheme object.
- If OBJ is not of type TYPE, then an error is signaled.
-
-
-
- struct gscm_type * type gscm_get_type (SCM * obj)
-
- *******************************************
- * NOTE!!! The obj parameter is passed by *
- * _address_, not by value. *
- *******************************************
-
- (See the documentation of gscm_2_str for an explanation
- of this warning).
-
- Return the type structure associated with a Scheme object.
- If the object is not of a type defined using gscm_alloc_obj,
- then NULL is returned.
-
-
- Storage allocated by gscm_alloc_obj is one of the three aforementioned
- safe locations to store data of SCM type (See the section ``The Type
- SCM'').
-
-
-
- * Print Functions:
- gscm_print_obj, gscm_lputc, gscm_lputs, gscm_lfwrite, gscm_lflush
-
- In the preceding section you were shown how to add new types to Scheme
- which include in their definition a print function -- a function that
- does the work of the standard Scheme procedures WRITE and DISPLAY for
- your type.
-
- Your print function is passed the object to print and a Scheme port
- on which to print its output. Here are some functions which you can
- use to write data to a Scheme port. [In the future, there will be more.]
-
- void gscm_print_obj (SCM obj, SCM port, int writingp)
-
- Print OBJ on PORT, either displaying or writing according to WRITINGP.
-
-
- void gscm_putc (int c, SCM port)
-
- Output a single character on a port.
-
-
-
- void gscm_puts (char * s, SCM port)
-
- Output a 0-terminated string on a port.
-
-
-
- int gscm_fwrite (char *ptr, sizet size, sizet nitems, SCM port)
-
- Comparable to fwrite, but for Scheme ports.
-
-
-
- void gscm_flush (SCM port)
-
- Comparable to the scheme procedure FORCE-OUTPUT.
-
-
-
-
- TIPS FOR DOCUMENTATION STRINGS
- ==============================
-
- Here are some tips for the writing of documentation strings.
-
- * Every command, function or variable intended for users to know
- about should have a documentation string.
-
- * An internal subroutine of a Lisp program need not have a
- documentation string, and you can save space by using a comment
- instead.
-
- * The first line of the documentation string should consist of one
- or two complete sentences which stand on their own as a summary.
- In particular, start the line with a capital letter and end with a
- period.
-
- The documentation string can have additional lines which expand on
- the details of how to use the function or variable. The
- additional lines should be made up of complete sentences also, but
- they may be filled if that looks good.
-
- * Do not start or end a documentation string with whitespace.
-
- * Format the documentation string so that it fits in an Emacs window
- on an 80 column screen. It is a good idea for most lines to be no
- wider than 60 characters. The first line can be wider if
- necessary to fit the information that ought to be there.
-
- However, rather than simply filling the entire documentation
- string, you can make it much more readable by choosing line breaks
- with care. Use blank lines between topics if the documentation
- string is long.
-
- * *Do not* indent subsequent lines of a documentation string so that
- the text is lined up in the source code with the text of the first
- line. This looks nice in the source code, but looks bizarre when
- users view the documentation. Remember that the indentation
- before the starting double-quote is not part of the string!
-
- * A variable's documentation string should start with `*' if the
- variable is one that users would want to set interactively often.
- If the value is a long list, or a function, or if the variable
- would only be set in init files, then don't start the
- documentation string with `*'. *Note Defining Variables::.
-
- * The documentation string for a variable that is a yes-or-no flag
- should start with words such as "Non-nil means...", to make it
- clear both that the variable only has two meaningfully distinct
- values and which value means "yes".
-
- * When a function's documentation string mentions the value of an
- argument of the function, use the argument name in capital letters
- as if it were a name for that value. Thus, the documentation
- string of the function `/' refers to its second argument as
- `DIVISOR'.
-
- Also use all caps for meta-syntactic variables, such as when you
- show the decomposition of a list or vector into subunits, some of
- which may be variable.
-
- * When a documentation string refers to a Lisp symbol, write it as it
- would be printed (which usually means in lower case), with
- single-quotes around it. For example: ``lambda''. There are two
- exceptions: write `t' and `nil' without single-quotes.
-
- * Don't write key sequences directly in documentation strings.
- Instead, use the `\\[...]' construct to stand for them. For
- example, instead of writing `C-f', write `\\[forward-char]'. When
- the documentation string is printed, Emacs will substitute
- whatever key is currently bound to `forward-char'. This will
- usually be `C-f', but if the user has moved key bindings, it will
- be the correct key for that user. *Note Keys in Documentation::.
-
- * In documentation strings for a major mode, you will want to refer
- to the key bindings of that mode's local map, rather than global
- ones. Therefore, use the construct `\\<...>' once in the
- documentation string to specify which key map to use. Do this
- before the first use of `\\[...]'. The text inside the `\\<...>'
- should be the name of the variable containing the local keymap for
- the major mode.
-
-
-